package org.jeecg.modules.project.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.exception.ParamCheckException;
import org.jeecg.modules.core.constant.YesOrNotEnum;
import org.jeecg.modules.project.entity.BimProjectBuild;
import org.jeecg.modules.project.entity.BimProjectFloor;
import org.jeecg.modules.project.entity.BuildResultType;
import org.jeecg.modules.project.entity.ProjectInfo;
import org.jeecg.modules.project.mapper.BimProjectBuildMapper;
import org.jeecg.modules.project.model.params.BimProjectFloorParam;
import org.jeecg.modules.project.model.result.BimProjectBuildInfo;
import org.jeecg.modules.project.service.IBimProjectBuildService;
import org.jeecg.modules.project.service.IBimProjectFloorService;
import org.jeecg.modules.project.service.IProjectInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: bim_project_build
 * @Author: jeecg-boot
 * @Date: 2023-04-13
 * @Version: V1.0
 */
@Service
public class BimProjectBuildServiceImpl extends ServiceImpl<BimProjectBuildMapper, BimProjectBuild> implements IBimProjectBuildService {

    @Autowired
    private IBimProjectFloorService bimProjectFloorService;

    @Autowired
    private IProjectInfoService projectInfoService;

    @Override
    @Transactional
    public void delete(String buildId) {
        this.removeById(buildId);
        List<BimProjectFloor> bimFloorList = new LambdaQueryChainWrapper<>(bimProjectFloorService.getBaseMapper())
                .eq(BimProjectFloor::getBuildId, buildId).list();
        if (CollUtil.isNotEmpty(bimFloorList)) {
            bimFloorList.stream().forEach(item -> bimProjectFloorService.removeById(item.getFloorId()));
        }
    }

    @Override
    public List<BimProjectBuild> add(List<BimProjectBuild> bimBuildList) {
        if (CollUtil.isNotEmpty(bimBuildList)) {
            List<BimProjectBuild> filterBuilds = bimBuildList.stream().filter(item -> ObjectUtil.isNotNull(item.getProjInfoId())).collect(Collectors.toList());
            if(CollUtil.isNotEmpty(filterBuilds)) {
                Map<Integer, List<BimProjectBuild>> projectBuildMap = filterBuilds.stream().collect(Collectors.groupingBy(BimProjectBuild::getProjInfoId));
                if (CollUtil.isNotEmpty(projectBuildMap) && projectBuildMap.size() > 1) {
                    throw new ParamCheckException("楼栋列表存在不一致的工程管理编码！");
                }
            }
            Map<Integer, List<BimProjectBuild>> buildNoBuildMap = bimBuildList.stream().collect(Collectors.groupingBy(BimProjectBuild::getBuildNo));
            buildNoBuildMap.keySet().stream().forEach(itemKey ->{
                List<BimProjectBuild> buildNoBuilds = buildNoBuildMap.get(itemKey);
                if(CollUtil.isNotEmpty(buildNoBuilds) && buildNoBuilds.size() > 1){
                    throw new ParamCheckException(MessageFormat.format("楼栋号重复：{0}", itemKey));
                }
            });
            BimProjectBuild headProjBuild = bimBuildList.get(0);
            if (ObjectUtil.isNull(headProjBuild.getProjInfoId())) {
                ProjectInfo projectInfo = new ProjectInfo();
                projectInfo.setEnableFlag(YesOrNotEnum.N.getCode());
                projectInfoService.save(projectInfo);
                bimBuildList.stream().forEach(item -> {
                    item.setProjInfoId(projectInfo.getId());
                });
            }
            bimBuildList.stream().forEach(item -> {
                if (!isUnique(item)) {
                    throw new ParamCheckException(MessageFormat.format("已经存在楼栋号：{0}", item.getBuildNo()));
                }
            });
            this.saveBatch(bimBuildList);
        }
        return bimBuildList;
    }

    @Override
    public List<BimProjectBuildInfo> editMap(List<BimProjectFloorParam> buildParamList) {
        if (CollUtil.isEmpty(buildParamList)) {
            throw new ParamCheckException("未提交楼层信息!");
        }
        BimProjectFloorParam headFloorParam = buildParamList.get(0);
        BimProjectBuild projectBuild = this.getById(headFloorParam.getBuildId());
        buildParamList.stream().forEach(item -> {
            BimProjectFloor projectFloor = bimProjectFloorService.getById(item.getFloorId());
            projectFloor.setMaps(JSONUtil.toJsonStr(item.getMaps()));
            bimProjectFloorService.updateById(projectFloor);
        });
        return projectInfoService.getProjBuildInfos(projectBuild.getProjInfoId(), BuildResultType.MAP);
    }

    @Override
    public void edit(BimProjectBuild bimProjectBuild) {
        BimProjectBuild query = new BimProjectBuild();
        query.setProjInfoId(bimProjectBuild.getProjInfoId());
        query.setBuildNo(bimProjectBuild.getBuildNo());
        if (!isUnique(query)) {
            throw new ParamCheckException(MessageFormat.format("已经存在楼栋号：{0}", query.getBuildNo()));
        }
        this.updateById(bimProjectBuild);
    }

    @Override
    public List<BimProjectBuild> queryBuild(BimProjectBuild build) {
        return new LambdaQueryChainWrapper<>(this.getBaseMapper())
                .eq(ObjectUtil.isNotNull(build.getProjInfoId()), BimProjectBuild::getProjInfoId, build.getProjInfoId())
                .eq(ObjectUtil.isNotNull(build.getBuildId()), BimProjectBuild::getBuildId, build.getBuildId())
                .eq(ObjectUtil.isNotNull(build.getBuildNo()), BimProjectBuild::getBuildNo, build.getBuildNo())
                .list();
    }

    public boolean isUnique(BimProjectBuild bimProjectBuild) {
        BimProjectBuild queryBuild = new LambdaQueryChainWrapper<>(this.getBaseMapper())
                .eq(BimProjectBuild::getProjInfoId, bimProjectBuild.getProjInfoId())
                .eq(BimProjectBuild::getBuildNo, bimProjectBuild.getBuildNo())
                .list().stream().findFirst().orElse(null);
        return queryBuild == null ? true : false;
    }
}
